package fun.sssdnsy.util;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 配置工具类
 * <p>
 * - 读取 / 保存 用户配置
 * - 配置文件存放于 `src/resources/config/configuration.json`
 *
 * @author pengzh
 * @since 2025-03-30
 */
public class ConfigUtil {

    private static final transient Logger log = LoggerFactory.getLogger(ConfigUtil.class);

    private static final String CONFIG_PATH = "/fun/sssdnsy/config/config.json";
    public static final String FACE_RECONIZE = "faceReconize";
    private static Map<String, Object> config;
    private static final ReadWriteLock RW_LOCK = new ReentrantReadWriteLock();

    public static final String ENCRYPT_FILE_PATH = "encryptFilePath";

    static {
        loadConfig();
    }


    /**
     * 读取配置文件
     */
    public static JSONObject loadConfig() {
        JSONObject jsonObject = null;
        try (InputStream input = ConfigUtil.class.getResourceAsStream(CONFIG_PATH)) {
            if (input == null) {
                log.warn("配置文件未找到，使用默认值。");
                jsonObject = new JSONObject();
                setDefaults();
                return jsonObject;
            }
            String content = new String(input.readAllBytes(), StandardCharsets.UTF_8);
            jsonObject = new JSONObject(content);
            log.info("已加载配置文件: ｛｝", FileUtil.getResourcePath(CONFIG_PATH).toString());
        } catch (IOException e) {
            log.error("配置文件加载失败，使用默认值。");
            jsonObject = new JSONObject();
            setDefaults();
        }
        config = jsonObject.toMap();
        return jsonObject;
    }

    /**
     * 获取配置值
     */
    public static String get(String key) {
        RW_LOCK.readLock().lock();
        Object value = config.getOrDefault(key, "");
        RW_LOCK.readLock().unlock();
        return value.toString();
    }


    /**
     * 获取配置值
     */
    public static String get(String key, String defaultValue) {
        RW_LOCK.readLock().lock();
        Object value = config.getOrDefault(key, defaultValue);
        RW_LOCK.readLock().unlock();
        return value==null?defaultValue: value.toString();

    }

    /**
     * 设置配置值
     */
    public static void set(String key, String value) {
        RW_LOCK.writeLock().lock();
        config.put(key, value);
        RW_LOCK.writeLock().unlock();
    }

    public static void save(String key, String value) {
        RW_LOCK.writeLock().lock();
        set(key, value);
        save();
        RW_LOCK.writeLock().unlock();
    }

    /**
     * 保存配置文件
     */
    public static void save(Map config) {
        RW_LOCK.writeLock().lock();
        // 深拷贝配置
        Map<String, Object> snapshot = new HashMap<>(config);
        CompletableFuture.runAsync(() -> {
                    try (FileWriter file = new FileWriter(FileUtil.getResourcePath(CONFIG_PATH))) {
                        JSONObject jsonObject = new JSONObject(snapshot);
                        file.write(jsonObject.toString(4));
                    } catch (IOException e) {
                        log.error("[错误] 配置文件保存失败！");
                    }
                }, ThreadPoolUtil.ASYNC_POOL)
                .exceptionally(throwable -> {
                    log.error(throwable.getMessage(), throwable);
                    return null;
                });
        RW_LOCK.writeLock().unlock();
    }

    /**
     * 保存配置文件
     */
    public static void save() {
        save(config);
    }

    /**
     * 设置默认配置
     */
    public static void setDefaults() {
        RW_LOCK.writeLock().lock();
        try {
            String systemLang = Locale.getDefault().getLanguage().equals("zh") ? "zh" : "en";
            config.put("language", systemLang);
            save();
        } finally {
            RW_LOCK.writeLock().unlock();
        }
    }

    public static void setShortcuts(Map<String, String> shortcuts) {
        RW_LOCK.writeLock().lock();
        config.put("shortcuts", shortcuts);
        RW_LOCK.writeLock().unlock();
    }

    public static Map<String, String> getShortcuts() {
        RW_LOCK.readLock().lock();
        Object shortcuts = config.getOrDefault("shortcuts", new HashMap<>());
        if (shortcuts instanceof Map map) {
            return map;
        }
        RW_LOCK.readLock().unlock();
        return new HashMap<>();
    }

}
